package com.muyu.filter;

import com.muyu.common.constant.JwtConstants;
import com.muyu.common.constant.TokenConstants;
import com.muyu.common.redis.service.RedisService;
import com.muyu.common.utils.JwtUtils;
import com.muyu.common.utils.StringUtils;
import com.muyu.config.IgnoreWhiteConfig;
import com.muyu.utils.GatewayUtils;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;

/**
 * @Author: DongZeLiang
 * @date: 2024/5/24
 * @Description: 权限过滤器
 * @Version: 1.0
 */
@Component
@AllArgsConstructor
public class AuthFilter implements GlobalFilter, Ordered {

    private final IgnoreWhiteConfig ignoreWhiteConfig;

    private final RedisService redisService;

    @Override
    public Mono<Void> filter (ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        URI uri = request.getURI();
        String path = uri.getPath();
        if (StringUtils.matches(path, ignoreWhiteConfig.getWhites())){
            return chain.filter(exchange);
        }
        HttpHeaders requestHeaders = request.getHeaders();
        String token = requestHeaders.getFirst(TokenConstants.TOKEN);
        if (StringUtils.isEmpty(token)){
            return GatewayUtils.errorResponse(exchange, "token不合法");
        }
        Claims claims = JwtUtils.parseToken(token);
        if (claims == null){
            return GatewayUtils.errorResponse(exchange, "token不合法");
        }
        String userKey = JwtUtils.getUserKey(claims);
        if (!redisService.hasKey(TokenConstants.LOGIN_TOKEN_KEY + userKey)){
            return GatewayUtils.errorResponse(exchange, "token已过期");
        }
        ServerHttpRequest.Builder mutate = request.mutate();
        GatewayUtils.addHeader(mutate, JwtConstants.USER_KEY, userKey);
        GatewayUtils.addHeader(mutate, JwtConstants.DETAILS_USER_ID, JwtUtils.getUserId(claims));
        GatewayUtils.addHeader(mutate, JwtConstants.DETAILS_USERNAME, JwtUtils.getUserName(claims));
        return chain.filter(exchange);
    }

    /**
     * Get the order value of this object.
     * <p>Higher values are interpreted as lower priority. As a consequence,
     * the object with the lowest value has the highest priority (somewhat
     * analogous to Servlet {@code load-on-startup} values).
     * <p>Same order values will result in arbitrary sort positions for the
     * affected objects.
     *
     * @return the order value
     *
     * @see #HIGHEST_PRECEDENCE
     * @see #LOWEST_PRECEDENCE
     */
    @Override
    public int getOrder () {
        return 0;
    }
}
